# -*- coding: utf-8 -*-
#
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import re
import warnings
from traceback import extract_stack

from rich.traceback import Frame, Stack, Trace, Traceback

from .logs import logger

LOG = logger(__name__)


class TestWarning(UserWarning):
    pass


def warn(test: bool, msg: str):
    if not test:
        LOG.warning(msg)
        warnings.warn(str(msg), TestWarning, stacklevel=2)


def _extract_traceback(level: int = 3) -> Traceback | None:
    call_stack = extract_stack(limit=level)[0]
    return (
        Traceback(
            Trace(
                stacks=[
                    Stack(
                        exc_type="",
                        exc_value="",
                        frames=[
                            Frame(
                                filename=call_stack.filename,
                                lineno=call_stack.lineno,  # type: ignore[arg-type]
                                line=call_stack.line,  # type: ignore[arg-type]
                                name=call_stack.name,
                            ),
                        ],
                    ),
                ],
            ),
        )
        if call_stack.lineno is not None and call_stack.line is not None
        else None
    )


def eq(a, b) -> None:
    try:
        assert a == b
    except AssertionError as e:
        m = re.match(".*", str(e))
        msg = m.group() if m else str(e)
        LOG.warning("%s", msg, rich=_extract_traceback())
        warnings.warn(TestWarning(e), category=TestWarning, stacklevel=2)
